
module frv_bdram_32 (
input                     clk ,
input   [15:0]          addra,
output  reg[31:0]            douta,

input   [15:0]            addr,
input   [31:0]            din ,
input   [3:0]             wen ,
output  reg[31:0]            dout
);

parameter  MEMDEPTH = 2**(16);

wire [31:0] inst_read;

reg [31:0] mem [(MEMDEPTH-1):0] /* synthesis syn_ramstyle = "no_rw_check" */;

// initial begin
//   $readmemh("E:/develop/frv232platform/tb/riscvtest/fib-riscv32-nemu.bin.data",_frv_bdram_32.mem);
// end

wire[7:0] mem_0 = mem[addr][7:0];
wire[7:0] mem_1 = mem[addr][15:8];
wire[7:0] mem_2 = mem[addr][23:16];
wire[7:0] mem_3 = mem[addr][31:24];

wire[7:0] memw_0 = wen[0] ? din[7:0] : mem_0;
wire[7:0] memw_1 = wen[1] ? din[15:8] :mem_1;
wire[7:0] memw_2 = wen[2] ? din[23:16] :mem_2;
wire[7:0] memw_3 = wen[3] ? din[31:24] :mem_3;

wire [31:0] memw_data = {memw_3,memw_2,memw_1,memw_0};

// wire TEST_JUDGE = mem[16'h008b] == 32'h0984_0913;

assign inst_read = mem[addra];

always @(posedge clk)
begin
  if(|wen)
  begin
    mem[addr]       <= memw_data;
    dout            <= din;
    douta           <= inst_read;
  end
  else
  begin
    dout            <= mem[addr];
    douta           <= inst_read;
  end
end

endmodule


module frv_ram(
  clk ,
  addr,
  din ,
  wen ,
  dout
);

parameter  DATAWIDTH = 2;
parameter  ADDRWIDTH = 2;

input                     clk ;
input   [(ADDRWIDTH-1):0] addr;
input   [(DATAWIDTH-1):0] din ;
input                     wen ;
output  [(DATAWIDTH-1):0] dout;

parameter  MEMDEPTH = 2**(ADDRWIDTH);

reg [(DATAWIDTH-1):0] mem [(MEMDEPTH-1):0] /* synthesis syn_ramstyle = "no_rw_check" */;
reg [(DATAWIDTH-1):0] dout;

initial begin
  $readmemh("E:/develop/frv232platform/tb/riscvtest/fib-riscv32-nemu.bin.data",_frv_ram.mem);
end
    
always @(posedge clk)
begin
  if(wen)
  begin
    mem[addr]       <= din;
    dout            <= din;
  end
  else
  begin
    dout            <= mem[addr];
  end
end

endmodule

module fpga_ram(
  PortAClk,
  PortAAddr,
  PortADataIn,
  PortAWriteEnable,
//  PortAChipEnable,
  PortADataOut
);

parameter  DATAWIDTH = 2;
parameter  ADDRWIDTH = 2;

input                     PortAClk;
input   [(ADDRWIDTH-1):0] PortAAddr;
input   [(DATAWIDTH-1):0] PortADataIn;
input                     PortAWriteEnable;
//input                     PortAChipEnable;
output  [(DATAWIDTH-1):0] PortADataOut; 

parameter  MEMDEPTH = 2**(ADDRWIDTH);

reg [(DATAWIDTH-1):0] mem [(MEMDEPTH-1):0] /* synthesis syn_ramstyle = "no_rw_check" */;
reg [(DATAWIDTH-1):0] PortADataOut;

always @(posedge PortAClk)
begin
  if(PortAWriteEnable)
  begin
    mem[PortAAddr]  <= PortADataIn;
    PortADataOut    <= PortADataIn;
  end
  else
  begin
    PortADataOut    <= mem[PortAAddr];
  end
end


endmodule
